home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 42 / Amiga Format AFCD42 (Issue 126, Aug 1999).iso / -serious- / comms / other / slrn / slrn_src / src / menu.c < prev    next >
C/C++ Source or Header  |  1999-05-14  |  20KB  |  894 lines

  1. /* -*- mode: C; mode: fold; -*- */
  2. /* Copyright (c) 1998 John E. Davis (davis@space.mit.edu)
  3.  *
  4.  * This file is part of slrn.
  5.  *
  6.  * Slrn is free software; you can redistribute it and/or modify it
  7.  * under the terms of the GNU General Public License as published by the
  8.  * Free Software Foundation; either version 2, or (at your option) any
  9.  * later version.
  10.  * 
  11.  * Slrn is distributed in the hope that it will be useful, but WITHOUT
  12.  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13.  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14.  * for more details.
  15.  * 
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with Slrn; see the file COPYING.  If not, write to the Free
  18.  * Software Foundation, 59 Temple Place - Suite 330, 
  19.  * Boston, MA  02111-1307, USA.
  20.  */
  21.  
  22. #include "config.h"
  23. #include "slrnfeat.h"
  24.  
  25. /*{{{ Include Files */
  26.  
  27. #include <stdio.h>
  28. #include <string.h>
  29.  
  30.  
  31. #ifdef HAVE_UNISTD_H
  32. # include <unistd.h>
  33. #endif
  34.  
  35. #ifdef HAVE_STDLIB_H
  36. # include <stdlib.h>
  37. #endif
  38.  
  39. #include <slang.h>
  40. #include "jdmacros.h"
  41.  
  42. #include "slrn.h"
  43. #include "menu.h"
  44. #include "misc.h"
  45. #include "util.h"
  46. #include "slrndir.h"
  47.  
  48. /*}}}*/
  49.  
  50. /*{{{ Menu Routines */
  51.  
  52. typedef struct /*{{{*/
  53. {
  54.    char *menu_name;
  55.    char *function_name;
  56. }
  57.  
  58. /*}}}*/
  59. Menu_Type;
  60.  
  61. static Menu_Type Group_Mode_Menu [] = /*{{{*/
  62. {
  63.      {"Quit", "quit"},
  64.      {"Refresh", "refresh_groups"},
  65.      {"Top", "bob"},
  66.      {"Bot", "eob"},
  67.      {"Post", "post"},
  68.      {"Help", "help"},
  69.      {NULL, NULL}
  70. };
  71.  
  72. /*}}}*/
  73.     
  74. static Menu_Type Article_Mode_Menu [] = /*{{{*/
  75. {
  76.      {"Quit", "quit"},
  77.      {"Catchup", "catchup_all"},
  78.      {"NextGrp", "skip_to_next_group"},
  79.      {"NextArt", "next"},
  80.      {"Top", "goto_beginning"},
  81.      {"Bot", "goto_end"},
  82.      {"Post", "post"},
  83.      {"Reply", "reply"},
  84.      {"Followup", "followup"},
  85.      {"Help", "help"},
  86.      {NULL, NULL}
  87. };
  88.  
  89. /*}}}*/
  90.  
  91. static Menu_Type *Current_Menu;
  92.  
  93. static void update_menu (Menu_Type *m) /*{{{*/
  94. {
  95.    int col;
  96.    
  97.    Current_Menu = m;
  98.    /* if (Slrn_Full_Screen_Update == 0) return; */
  99.    SLsmg_gotorc (0, 0);
  100.    slrn_set_color (MENU_COLOR);
  101.    if (m != NULL) while (m->menu_name != NULL)
  102.      {
  103.     SLsmg_write_string (m->menu_name);
  104.     SLsmg_write_string ("   ");
  105.     m++;
  106.      }
  107.    
  108.    SLsmg_erase_eol ();
  109.  
  110.    col = SLtt_Screen_Cols - 16;
  111.    if (SLsmg_get_column () < col)
  112.      SLsmg_gotorc (0, col);
  113.    
  114.    SLsmg_write_string ("slrn ");
  115.    SLsmg_write_string (Slrn_Version);
  116.    
  117.    slrn_set_color (0);
  118. }
  119.  
  120. /*}}}*/
  121.  
  122. int slrn_execute_menu (int want_col) /*{{{*/
  123. {
  124.    Menu_Type *m;
  125.    int col;
  126.    int color;
  127.    
  128.    if ((want_col < 0) || (want_col >= SLtt_Screen_Cols)) return -1;
  129.    
  130.    m = Current_Menu;
  131.    if (m == NULL) return -1;
  132.    
  133.    col = -1;
  134.    while (m->menu_name != NULL)
  135.      {
  136.     int dcol = 2 + strlen (m->menu_name);
  137.     if ((want_col > col) 
  138.         && (want_col <= col + dcol))
  139.       break;
  140.     col += dcol + 1;
  141.     m++;
  142.      }
  143.    if (m->menu_name == NULL) return -1;
  144.    
  145.    slrn_push_suspension (0);
  146.    /* redraw menu item so that user sees that it has been pressed */
  147.    if (col == -1) col = 0;
  148.    color = MENU_PRESS_COLOR;
  149.    SLsmg_gotorc (0, col);
  150.    while (1)
  151.      {
  152.     slrn_set_color (color);
  153.     if (col) SLsmg_write_char (' ');
  154.     SLsmg_write_string (m->menu_name);
  155.     SLsmg_write_char (' ');
  156.     SLsmg_gotorc (0, col);
  157.     slrn_smg_refresh ();
  158.     if (color == MENU_COLOR) break;
  159.     (void) SLang_input_pending (1);           /* 1/10 sec */
  160.     color = MENU_COLOR;
  161.      }
  162.    slrn_set_color (0);
  163.    slrn_pop_suspension ();
  164.  
  165.    slrn_call_command (m->function_name);
  166.  
  167.    return 0;
  168. }
  169.  
  170. /*}}}*/
  171.    
  172. void slrn_update_article_menu (void) /*{{{*/
  173. {
  174.    update_menu (Article_Mode_Menu);
  175. }
  176.  
  177. /*}}}*/
  178.  
  179. void slrn_update_group_menu (void) /*{{{*/
  180. {
  181.    update_menu (Group_Mode_Menu);
  182. }
  183.  
  184. /*}}}*/
  185.  
  186. /*}}}*/
  187.  
  188. /*{{{ Selection Box Routines */
  189.  
  190. static char *Sort_Selections [] = /*{{{*/
  191. {
  192.    "No sorting",               /* 000 */
  193.      "Thread Headers",               /* 001 */
  194.      "Sort by subject",               /* 010 */
  195.      "Thread, then sort by subject.",  /* 011 */
  196.      "Sort by scores.",               /* 100 */
  197.      "Thread, then sort by scores.",   /* 101 */
  198.      "Sort by score and subject",      /* 110 */
  199.      "Thread, then sort by score and subject",   /* 111 */
  200.      "Sort by date (most recent first)",               /* 1000 */
  201.      "Thread, then sort by date (most recent first)",      /* 1001 */
  202.      "Sort by date (most recent last)",      /* 1010 */
  203.      "Thread, then Sort by date (most recent last)",      /* 1011 */
  204.      NULL
  205. };
  206.  
  207. /*}}}*/
  208.  
  209. static Slrn_Select_Box_Type Slrn_Sort_Select_Box = /*{{{*/
  210. {
  211.    "Sorting Method", Sort_Selections
  212. };
  213.  
  214. /*}}}*/
  215.  
  216. static void center_string_column (char *title, int row, int col, int num_columns) /*{{{*/
  217. {
  218.    int c;
  219.    int len = strlen (title);
  220.    
  221.    c = (num_columns - len) / 2;
  222.    if (c < 0) c = 0;
  223.    
  224.    c += col;
  225.    SLsmg_gotorc (row, c); 
  226.    SLsmg_write_string (title);
  227. }
  228.  
  229. /*}}}*/
  230.  
  231. static int draw_select_box (Slrn_Select_Box_Type *sb) /*{{{*/
  232. {
  233.    int num_selections, max_selection_len;
  234.    int num_rows, num_columns;
  235.    int len;
  236.    int row, column, r, c;
  237.    char **lines, *line, *title;
  238.    static Slrn_Select_Box_Type *last_sb;
  239.    
  240.    if ((sb == NULL) && ((sb = last_sb) == NULL))
  241.      return -1;
  242.    
  243.    last_sb = sb;
  244.    
  245.    lines = sb->lines;
  246.    title = sb->title;
  247.  
  248.    slrn_push_suspension (0);
  249.    
  250.    if (title == NULL) title = "";
  251.    max_selection_len = strlen (title);
  252.    num_selections = 0;
  253.    while ((line = *lines) != NULL)
  254.      {    
  255.     len = strlen (line);
  256.     if (len > max_selection_len) max_selection_len = len;
  257.     num_selections++;
  258.     lines++;
  259.      }
  260.  
  261.    /* allow room for title, blank line, top, bottom */
  262.    num_rows = num_selections + 4 + 2;
  263.    num_columns = max_selection_len + (3 + 3);
  264.    
  265.    row = (SLtt_Screen_Rows - num_rows) / 2;
  266.    if (row < 0) row = 0;
  267.    column = (SLtt_Screen_Cols - num_columns) / 2;
  268.    if (column < 0) column = 0;
  269.  
  270.    slrn_set_color (BOX_COLOR);
  271.    SLsmg_fill_region (row, column, num_rows, num_columns, ' ');
  272.    
  273.    r = row + 1;
  274.    center_string_column (title, r, column, num_columns);
  275.    
  276.    lines = sb->lines;
  277.    
  278.    
  279.    num_selections = 0;
  280.    c = column + 1;
  281.    r += 1;
  282.    while ((line = *lines) != NULL)
  283.      {
  284.     lines++;
  285.     r++;
  286.     SLsmg_gotorc (r, c);
  287.     SLsmg_printf ("%2X %s", num_selections, line);
  288.     num_selections++;
  289.      }
  290.    
  291.    r += 2;
  292.    center_string_column ("(Select One)", r, column, num_columns);
  293.                       
  294.    slrn_set_color (FRAME_COLOR);
  295.    SLsmg_draw_box (row, column, num_rows, num_columns);
  296.    slrn_set_color (0);
  297.    
  298.    slrn_smg_refresh ();
  299.    
  300.    slrn_pop_suspension ();
  301.    
  302.    return num_selections;
  303. }
  304.  
  305. /*}}}*/
  306.  
  307. static void select_box_redraw (void) /*{{{*/
  308. {
  309.    slrn_push_suspension (0);
  310.    draw_select_box (NULL);
  311.    Slrn_Full_Screen_Update = 1;
  312.    slrn_pop_suspension ();
  313. }
  314.  
  315. /*}}}*/
  316.  
  317. static Slrn_Mode_Type Menu_Mode_Cap = 
  318. {
  319.    NULL,                   /* keymap */
  320.    select_box_redraw,               /* redraw_fun */
  321.    NULL,                   /* sigwinch_fun */
  322.    NULL,                   /* hangup_fun */
  323.    NULL,                   /* enter_mode_hook */
  324.    SLRN_MENU_MODE
  325. };
  326.  
  327. int slrn_select_box (Slrn_Select_Box_Type *sb) /*{{{*/
  328. {
  329.    int num_selections;
  330.    int rsp;
  331.    
  332.    if (Slrn_Batch)
  333.      return -1;
  334.  
  335.    slrn_push_mode (&Menu_Mode_Cap);
  336.  
  337.    num_selections = draw_select_box (sb);
  338.    
  339.    Slrn_Full_Screen_Update = 1;
  340.    rsp = SLang_getkey ();
  341.  
  342.    slrn_pop_mode ();
  343.    
  344.    if (rsp >= 'A')
  345.      {
  346.     rsp = 10 + ((rsp | 0x20) - 'a');
  347.      }
  348.    else rsp = rsp - '0';
  349.    
  350.    if ((rsp < 0) || (rsp >= num_selections))
  351.      {
  352.     slrn_error ("Cancelled.");
  353.  
  354.     while (SLang_input_pending (2))
  355.       (void) SLang_getkey ();
  356.     
  357.     return -1;
  358.      }
  359.    
  360.    return rsp;
  361. }
  362.  
  363. /*}}}*/
  364.  
  365. int slrn_sbox_sorting_method (void) /*{{{*/
  366. {
  367.    return slrn_select_box (&Slrn_Sort_Select_Box);
  368. }
  369.  
  370. /*}}}*/
  371.  
  372. /*}}}*/
  373.  
  374. typedef struct Select_List_Type
  375. {
  376.    struct Select_List_Type *next;
  377.    struct Select_List_Type *prev;
  378.    unsigned int flags;
  379.    char *data;
  380. }
  381. Select_List_Type;
  382.  
  383. static SLscroll_Window_Type *Select_Window;
  384. static unsigned int Select_List_Window_Row;
  385. static unsigned int Select_List_Window_Col;
  386. static unsigned int Select_List_Window_Ncols;
  387. static int Select_List_Active_Color = SELECT_COLOR;
  388. static char *Select_List_Title = ".";
  389.  
  390. static void draw_select_list (void)
  391. {
  392.    unsigned int r;
  393.    Select_List_Type *l;
  394.    int row, column;
  395.